﻿/********************************************************************
	created:	2015/07/06  16:54
	file base:	CSVReader
	file ext:	cs
	author:		github tikonen
	
	purpose:	CSV的读取，只需要将csv文件放置在Resource下某目录即可，比如放在resource/data下，那么：
                CSVReader testReader = new CSVReader();
                testReader.Load("data/example");
                testReader.PrintData();
                string testValue = testReader.getById("1", "name");
                int testIntValue = testReader.getIntById("2", "age");
                float testFloatValue = testReader.getFloatById("3", "speed");
*********************************************************************/
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;

public class CSVReader
{
	static string SPLIT_RE = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
	static string LINE_SPLIT_RE = @"\r\n|\n\r|\n|\r";

    private string m_fileName = "";
    private int m_keyNum = -1;
    private List<Dictionary<string, string>> m_dataList = new List<Dictionary<string, string>>();

    public List<Dictionary<string, string>> DataList
    {
        get { return m_dataList; }
        set { m_dataList = value; }
    }
    public CSVReader(string fileName)
    {
        Load(fileName);
    }

    /// <summary>
    /// 载入指定的csv文件，并进行初始化
    /// </summary>
    /// <param name="fileName"></param>
    public void Load(string fileName)
    {
        m_fileName = fileName;
        Read(m_fileName);
        InitKeyNum();
    }

    /// <summary>
    /// 读取指定的csv文件
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
	private void Read(string file)
	{
		TextAsset data = Resources.Load (file) as TextAsset;

        if (data != null)
        {
            var lines = Regex.Split(data.text, LINE_SPLIT_RE);

            if (lines.Length <= 2) return;

            var header = Regex.Split(lines[1], SPLIT_RE);
            for (var i = 2; i < lines.Length; i++)
            {

                var values = Regex.Split(lines[i], SPLIT_RE);
                if (values.Length == 0 || values[0] == "") continue;

                var entry = new Dictionary<string, string>();
                for (var j = 0; j < header.Length && j < values.Length; j++)
                {
                    string value = values[j];
                    entry[header[j]] = value;
                }
                m_dataList.Add(entry);
            }
        }
        else
        {
#if UNITY_EDITOR
            Debug.Log("CSV file does not exist: " + file);
#endif
        }
	}

    /// <summary>
    /// 得到Key的数目
    /// </summary>
    private void InitKeyNum()
    {      
        if (m_dataList.Count > 0)
        {
            m_keyNum = 0;
            Dictionary<string, string> firstData = m_dataList[0];
            m_keyNum = firstData.Count;
        }
    }

    /// <summary>
    /// 打印数据，用于调试
    /// </summary>
    public void PrintData()
    {
#if UNITY_EDITOR
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < m_dataList.Count; ++i)
        {
            foreach (KeyValuePair<string, string> keyValue in m_dataList[i])
            {
                string valueString = keyValue.Value.ToString();
                stringBuilder.Append(valueString);
                stringBuilder.Append(",");
            }
            stringBuilder.Append("\n");
        }

        Debug.Log("CSV file: " + m_fileName + ", data is: \n" + stringBuilder.ToString());
#endif
    }

    /// <summary>
    /// 返回行数
    /// </summary>
    /// <returns></returns>
    public int num()
    {
        return m_dataList.Count;
    }

    /// <summary>
    /// 返回key的个数
    /// </summary>
    /// <returns></returns>
    public int keynum()
    {
        return m_keyNum;
    }

    /// <summary>
    /// 获得指定行的指定属性名的值(string)
    /// </summary>
    /// <param name="dataIdx"></param>
    /// <param name="typeName"></param>
    /// <returns></returns>
    public string get(int dataIdx, string typeName)
    {
        string ret = "";
        bool foundFlag = false;
        if (m_dataList.Count >= dataIdx)
        {
            foreach (KeyValuePair<string, string> keyValue in m_dataList[dataIdx])
            {
                if (keyValue.Key == typeName)
                {
                    foundFlag = true;
                    ret = keyValue.Value;
                    break;
                }
            }
        }
        else
        {
#if UNITY_EDITOR
            Debug.LogError("data index out of range, fileName is: " + m_fileName + ", dataIdx: " + dataIdx);
#endif
        }

        if (!foundFlag)
        {
#if UNITY_EDITOR
            Debug.LogError("can not found, fileName is: " + m_fileName + ", typeName: " + typeName);
#endif
        }

        return ret;
    }

    /// <summary>
    /// 获得指定行的指定属性名的值（int）
    /// </summary>
    /// <param name="dataIdx">行索引</param>
    /// <param name="typeName">属性名</param>
    /// <returns></returns>
    public int getInt(int dataIdx, string typeName)
    {
        string strItm = get(dataIdx, typeName);

        return int.Parse(strItm);
    }

    /// <summary>
    /// 获得指定行的指定属性名的值（float）
    /// </summary>
    /// <param name="dataIdx">行索引</param>
    /// <param name="typeName">属性名</param>
    /// <returns></returns>
    public float getFloat(int dataIdx, string typeName)
    {
        string strItm = get(dataIdx, typeName);

        return float.Parse(strItm);
    }


    /// <summary>
    /// 通过id和列名获取内容
    /// </summary>
    /// <param name="id"></param>
    /// <param name="typeName"></param>
    /// <returns></returns>
    public string getById(string id, string typeName)
    {
        if (m_keyNum == -1)
        {
            Debug.Log(typeName + "   " + id + "  error");
            return "-1";
        }

        for (int i = 0; i < m_dataList.Count; ++i)
        {
            int dictCount = 0;
            bool foundRecord = false;
            foreach (KeyValuePair<string, string> keyValue in m_dataList[i])
            {
                if (dictCount == 0 && keyValue.Value == id)
                {
                    foundRecord = true;
                }

                dictCount++;

                if (foundRecord && keyValue.Key == typeName)
                {
                    return keyValue.Value;
                }
            }
        }

        return "-1";
    }

    /// <summary>
    /// 转换get的类型为int返回
    /// </summary>
    /// <param name="id">id</param>
    /// <param name="typeName">列名</param>
    /// <returns></returns>
    public int getIntById(string id, string typeName)
    {
        string strItm = getById(id, typeName);
        return int.Parse(strItm);
    }

    /// <summary>
    /// 转换get的类型为float返回
    /// </summary>
    /// <param name="id">id</param>
    /// <param name="typeName">列名</param>
    /// <returns></returns>
    public float getFloatById(string id, string typeName)
    {
        string strItm = getById(id, typeName);
        return float.Parse(strItm);
    }
}
